package com.bishe.app.modules.group.controller;

import com.bishe.app.core.api.CommonResult;
import com.bishe.app.core.api.CommonPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bishe.app.core.enums.Is;
import com.bishe.app.core.enums.IsDel;
import com.bishe.app.core.utils.AppRunnerUtils;
import com.bishe.app.core.utils.Lock;
import com.bishe.app.modules.group.model.AddGroupLeader;
import com.bishe.app.modules.group.model.GroupNum;
import com.bishe.app.modules.group.model.GroupUserList;
import com.bishe.app.modules.groupuser.entity.GroupUser;
import com.bishe.app.modules.groupuser.enums.GroupUserPosition;
import com.bishe.app.modules.groupuser.service.GroupUserService;
import com.bishe.app.modules.user.entity.User;
import com.bishe.app.modules.user.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import com.bishe.app.modules.group.service.GroupService;
import com.bishe.app.modules.group.entity.Group;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;


/**
 * <p>
 * 组织表 前端控制器
 * </p>
 *
 * @author
 * @since 2024-03-13
 */
@RestController
@RequestMapping("/group")
public class GroupController {

    @Autowired
    public GroupService groupService;

    @Resource
    private GroupUserService groupUserService;

    @Resource
    private UserService userService;

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    @ResponseBody
    @Lock(lockPrefix = "/group",key = "lock", lockSecond = 60)
    public CommonResult create(@RequestBody Group group) {
        boolean success = groupService.save(group);
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }

    @RequestMapping(value = "/update/{id}", method = RequestMethod.POST)
    @ResponseBody
    @Lock(lockPrefix = "/group",key = "lock", lockSecond = 60)
    public CommonResult update(@PathVariable Long id, @RequestBody Group group) {
        group.setId(id);
        boolean success = groupService.updateById(group);
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    @ResponseBody
    @Lock(lockPrefix = "/group",key = "lock", lockSecond = 60)
    public CommonResult delete(@PathVariable Long id) {
        boolean success = groupService.removeById(id);
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }

    @RequestMapping(value = "/deleteSoft/{id}", method = RequestMethod.POST)
    @ResponseBody
    @Lock(lockPrefix = "/group",key = "lock", lockSecond = 60)
    public CommonResult deleteSoft(@PathVariable Long id) {
        boolean success = groupService.lambdaUpdate()
                .eq(Group::getId, id)
                .set(Group::getIsDel, IsDel.Y.getCode())
                .update();
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    @Lock(lockPrefix = "/group",key = "lock", lockSecond = 60)
    public CommonResult deleteBatch(@RequestParam("ids") List<Long> ids) {
        boolean success = groupService.removeByIds(ids);
        if (success) {
            return CommonResult.success(null);
        }
        return CommonResult.failed();
    }

    @RequestMapping(value = "/listAllGroupUser/{groupId}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<GroupUserList>> listAllGroupUser(@PathVariable Long groupId) {
        List<GroupUser> list = groupUserService.lambdaQuery()
                .eq(GroupUser::getGroupId, groupId)
                .eq(GroupUser::getIsDel, IsDel.N.getCode())
                .list();
        if (CollectionUtils.isEmpty(list)) {
            return CommonResult.success(new ArrayList<>());
        }

        List<GroupUserList> userList = list.stream().map(x -> {
            User user = userService.lambdaQuery()
                    .eq(User::getId, x.getUserId())
                    .eq(User::getIsDel, IsDel.N.getCode())
                    .one();
                    if (user == null) {
                        return null;
                    }
                    // data security
            user.setPwd(null);
            GroupUserList gul = new GroupUserList();
            BeanUtils.copyProperties(user, gul);
            gul.setLeaderId(x.getLeader());
            gul.setLeaderName(GroupUserPosition.ofCode(x.getLeader()).getDesc());
            return gul;
                }).filter(Objects::nonNull).sorted((o1, o2) -> o2.getLeaderId().compareTo(o1.getLeaderId()))
                .collect(Collectors.toList());

        return CommonResult.success(userList);
    }

    @RequestMapping(value = "/listAllGroupUser/withDel/{groupId}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<GroupUserList>> listAllGroupUserWithDel(@PathVariable Long groupId) {
        List<GroupUser> list = groupUserService.lambdaQuery()
                .eq(GroupUser::getGroupId, groupId)
                .eq(GroupUser::getIsDel, IsDel.N.getCode())
                .list();
        if (CollectionUtils.isEmpty(list)) {
            return CommonResult.success(new ArrayList<>());
        }

        List<GroupUserList> userList = list.stream().map(x -> {
            User user = userService.lambdaQuery()
                    .eq(User::getId, x.getUserId())
//                    .eq(User::getIsDel, IsDel.N.getCode())
                    .one();
                    if (user == null) {
                        return null;
                    }
                    // data security
            user.setPwd(null);
            GroupUserList gul = new GroupUserList();
            BeanUtils.copyProperties(user, gul);
            gul.setLeaderId(x.getLeader());
            gul.setLeaderName(GroupUserPosition.ofCode(x.getLeader()).getDesc());
            return gul;
                }).filter(Objects::nonNull).sorted((o1, o2) -> o2.getLeaderId().compareTo(o1.getLeaderId()))
                .collect(Collectors.toList());

        return CommonResult.success(userList);
    }




    @RequestMapping(value = "/getGroupPositions/{groupId}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult getGroupPositions(@PathVariable("groupId") Long groupId) {
        Group group = groupService.getById(groupId);
        return CommonResult.success(GroupUserPosition.getPositionMap(group.getType()));
    }

    @RequestMapping(value = "/getGroupPositions/v2/{groupId}", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult getGroupPositionsv2(@PathVariable("groupId") Long groupId) {
        Group group = groupService.getById(groupId);
        return CommonResult.success(GroupUserPosition.getPositionMap(group.getType()));
    }


    @RequestMapping(value = "/listAll", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<GroupNum>> listAll() {
        List<Group> groupList = groupService.lambdaQuery().eq(Group::getIsDel, IsDel.N.getCode()).list();
        if (!CollectionUtils.isEmpty(groupList)) {
            List<GroupNum> collect = groupList.stream()
                    .map(group -> {
                        GroupNum groupNum = new GroupNum();
                        BeanUtils.copyProperties(group, groupNum);

                        Long nums = groupUserService.lambdaQuery()
                                .eq(GroupUser::getGroupId, group.getId())
                                .eq(GroupUser::getIsDel, IsDel.N.getCode())
                                .count();
                        groupNum.setUserNums(nums);
//
//                        GroupUser one = groupUserService.lambdaQuery()
//                                .eq(GroupUser::getGroupId, group.getId())
//                                .eq(GroupUser::getIsDel, IsDel.N.getCode())
//                                .eq(GroupUser::getLeader, Is.Y.getCode())
//                                .one();

//                        User user = null;
//                        if (one != null) {
//                            user = userService.getById(one.getUserId());
//                        }
//                        groupNum.setLeaderUser(user);

                        return groupNum;
                    }).collect(Collectors.toList());
            return CommonResult.success(collect);
        }
        return CommonResult.success(new ArrayList<>());
    }

    @RequestMapping(value = "/pageList", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<CommonPage<Group>> page(@RequestBody CommonPage commonPage) {
        Page<Group> page = new Page(commonPage.getPageNum(), commonPage.getPageSize());
        return CommonResult.success(CommonPage.restPage(groupService.page(page)));
    }


    @RequestMapping(value = "/addGroupLeader", method = RequestMethod.POST)
    @ResponseBody
    @Lock(lockPrefix = "/group",key = "lock", lockSecond = 60)
    public CommonResult<String> addGroupLeader(@RequestBody AddGroupLeader addGroupLeader) {
        // 先更新老group
        if (Objects.nonNull(addGroupLeader.getOldLeaderUserId())) {
            groupUserService.lambdaUpdate()
                    .set(GroupUser::getLeader, Is.N.getCode())
                    .eq(GroupUser::getGroupId, addGroupLeader.getGroupId())
                    .eq(GroupUser::getUserId, addGroupLeader.getOldLeaderUserId())
                    .eq(GroupUser::getIsDel, IsDel.N.getCode())
                    .update();
        }

        // 再更新
        groupUserService.lambdaUpdate()
                .set(GroupUser::getLeader, Is.Y.getCode())
                .eq(GroupUser::getGroupId, addGroupLeader.getGroupId())
                .eq(GroupUser::getUserId, addGroupLeader.getNewLeaderUserId())
                .eq(GroupUser::getIsDel, IsDel.N.getCode())
                .update();

        return CommonResult.success("OK");
    }

    @RequestMapping(value = "/listAllGroupId", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<List<Group>> listGroup(Integer type) {
        List<Group> list = groupService.lambdaQuery()
                .eq(Group::getIsDel, IsDel.N.getCode())
                .eq(Objects.nonNull(type), Group::getType, type)
                .list();

        return CommonResult.success(list);
    }

//    @RequestMapping(value = "/getCurShopList", method = RequestMethod.GET)
//    @ResponseBody
//    public CommonResult<List<Group>> getCurShop() {
//        User user = AppRunnerUtils.getUser();
//
//
//        List<GroupUser> groupUserList = groupUserService.lambdaQuery()
//                .eq(GroupUser::getUserId, user.getId())
//                .eq(GroupUser::getIsDel, IsDel.N.getCode())
//                .list();
//
//        if(CollectionUtils.isEmpty(groupUserList)){
//            return
//        }
//
//        List<Group> list = groupService.lambdaQuery()
//                .eq(Group::getIsDel, IsDel.N.getCode())
//                .eq(Objects.nonNull(type), Group::getType, type)
//                .list();
//
//        return CommonResult.success(list);
//    }
}



